<script setup>
import {marked} from 'marked';
import DOMPurify from 'dompurify';
import { postStream } from '@/api/deepseek';
import {ref,onMounted,nextTick} from 'vue'


const currentMessages=ref([])
const inputMessage = ref('')
const errorMessage = ref('')
const currentBotMessage=ref('')
const isStreaming=ref(false)
const abortController=ref()
const conversationId=ref()
// const userAvatar=ref()
// const  botAvatar=ref()

  onMounted(()=>{
     generateConversationId()
  })

const generateConversationId=()=> {
conversationId.value = 'conv-' + Date.now();
}

const renderMarkdown=(content) =>{
  content = content || '';
  content = content.replace(/<think>/g, '<div class="thinking-container"><img src="https://cdn-icons-png.flaticon.com/512/1055/1055687.png" class="thinking-icon"><span class="deepThink">');
  if (!content.includes('</think>')) {
    content = content.concat('</span></div>');
  }
  if (content.includes('</think>')) {
    content = content.replace(/<\/span><\/div>/g, '');
    content = content.replace(/<\/think>/g, '</span></div>');
  }
  const html = marked(content);
  const sanitizedHtml = DOMPurify.sanitize(html);
  const tempDiv = document.createElement('div');
  tempDiv.innerHTML = sanitizedHtml.toString();
  const deepThinkElements = tempDiv.querySelectorAll('.deepThink');
  deepThinkElements.forEach((element) => {
    if (element.textContent.trim() === '') {
      element.textContent = '暂无推理过程';
    }
  });
  return tempDiv.innerHTML;
}
const handleSend=async ()=> {
  if (!inputMessage.value.trim() || isStreaming.value) return;
  abortController.value = new AbortController();
  const userMessage = {
    sender: 'user',
    text: inputMessage.value,
    conversationId: conversationId.value
  };
  currentMessages.value.push(userMessage);
  const botMessageIndex = currentMessages.value.length;
  currentMessages.value.push({
    sender: 'system',
    text: '',
    completed: false,
    conversationId: conversationId.value
  });
  const conversationHistory = buildConversationHistory();
  inputMessage.value = '';
  isStreaming.value = true;
  currentBotMessage.value = '';
  try {
    const response = await postStream({
      messages: conversationHistory,
      model: "deepseek-chat",
      stream: true,
      conversation_id:conversationId.value
    }, {
      signal: abortController.value.signal
    });
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    while (isStreaming.value) {
      const { done, value } = await reader.read();
      if (done) break;
      const text = decoder.decode(value);
      const lines = text.split('\n\n').filter(line => line.trim());
      for (const line of lines) {
        if (line.trim() === 'data: [DONE]') {
          finishGeneration(botMessageIndex);
          return;
        }
        if (line.startsWith('data: ')) {
          try {
            const jsonStr = line.substring(6);
            const data = JSON.parse(jsonStr);
            if (data.choices?.[0]?.delta?.content) {
            currentBotMessage.value += data.choices[0].delta.content;
              currentMessages.value[botMessageIndex]= {
                sender: 'system',
                text:currentBotMessage.value,
                completed: false,
                conversationId: conversationId.value
              }
             nextTick(() => {
                const container = document.querySelector('.chat-messages');
                container.scrollTop = container.scrollHeight;
              });
            }
          } catch (e) {
            console.error('解析JSON出错:', e);
          }
        }
      }
    }
  } catch (error) {
    if (error.name !== 'AbortError') {
      console.error('流式请求出错:', error);
      errorMessage.value = '请求出错: ' + error.message;
      currentMessages.value[botMessageIndex]= {
        sender: 'system',
        text: '请求出错: ' + error.message,
        completed: true,
        conversationId: conversationId.value
      }
    }
  } finally {
    if (isStreaming.value) {
    finishGeneration(botMessageIndex);
    }
  }
}
const buildConversationHistory=()=> {
  const currentConversationMessages = currentMessages.value.filter(
    msg => msg.conversationId === conversationId.value
  );
  const recentMessages = currentConversationMessages.slice(-10);
  return recentMessages.map(message => {
    return {
      role: message.sender === 'user' ? 'user' : 'assistant',
      content: message.text
    };
  });
}
const finishGeneration=(index)=> {
isStreaming.value = false;
  if (abortController.value) {
  abortController.value.abort();
    abortController.value= null;
  }
currentMessages.value[ index] ={
    ...currentMessages.value[index],
    completed: true
  }
}
const handleButtonClick=()=> {
  if (isStreaming.value) {
    finishGeneration(currentMessages.value.length - 1);
  } else {
    handleSend();
  }
}
// const startNewConversation=() =>{
//   generateConversationId();
// }
</script>
<template>

      <div class="chat-content">
        <div class="chatBox">
          <div v-if="errorMessage" class="error-message">
            {{ errorMessage }}
          </div>
          <div class="chat-messages">
            <div v-for="(message, index) in currentMessages" :key="index" class="message">
              <div v-if="message.sender === 'user'" class="user-message-container">
                <article class="message-content user-message">{{ message.text }}</article>
                <img src="../assets/images/people.jpg" class="avatar user-avatar" alt="用户头像">
              </div>
              <div v-else class="bot-message-container">
                <img src="../assets/images/robbit.jpg" class="avatar bot-avatar" alt="机器人头像">
                <article
                  class="message-content bot-message"
                  v-html="renderMarkdown(message.text)"
                  :data-completed="message.completed || !isStreaming"
                ></article>
              </div>
            </div>
          </div>
          <div class="chat-input">
            <textarea
              v-model="inputMessage"
              placeholder="请输入您的问题"
              @keyup.enter.exact="handleSend"
              rows="6"
              :disabled="isStreaming"
            />
            <button @click="handleButtonClick" :disabled="!inputMessage.trim() && !isStreaming">
              {{ isStreaming ? '停止生成' : '发送' }}
            </button>
          </div>
        </div>
      </div>
</template>


<style scoped>
.chat-content {
  width: 100%;
  height: 100vh;
  padding: 15px;
  box-sizing: border-box;
}
.chatBox {
  display: flex;
  flex-direction: column;
  height: 92%;
  width: 100%;
  border: 1px solid #e0e0e0;
  border-radius: 10px;
  overflow: hidden;
  background-color: white;
}
.error-message {
  background-color: #f8d7da;
  color: #721c24;
  padding: 12px;
  margin-bottom: 12px;
  border-radius: 8px;
  text-align: center;
}
.chat-messages {
  flex: 1;
  padding: 15px;
  overflow-y: auto;
}
.message {
  margin-bottom: 15px;
  display: flex;
  align-items: flex-start;
}
.user-message-container {
  display: flex;
  justify-content: flex-end;
  width: 100%;
  align-items: flex-start;
  gap: 10px;
}
.bot-message-container {
  display: flex;
  justify-content: flex-start;
  width: 100%;
  align-items: flex-start;
  gap: 10px;
}
.avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}
.user-avatar {
  border: 2px solid #2196f3;
}
.bot-avatar {
  border: 2px solid #4caf50;
}
.message-content {
  max-width: calc(80% - 50px);
  padding: 10px 15px;
  border-radius: 18px;
  line-height: 1.4;
  word-wrap: break-word;
}
.user-message {
  background-color: #e3f2fd;
  margin-left: 20%;
}
.bot-message {
  background-color: #f5f5f5;
  margin-right: 20%;
}
.chat-input {
  display: flex;
  padding: 15px;
  border-top: 1px solid #e0e0e0;
  background-color: #fff;
}
.chat-input textarea {
  flex: 1;
  padding: 12px;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  margin-right: 12px;
  resize: none;
  min-height: 60px;
  max-height: 150px;
  font-family: inherit;
  font-size: 14px;
}
.chat-input textarea:focus {
  outline: none;
  border-color: #2196f3;
}
.chat-input button {
  padding: 0 20px;
  height: 48px;
  background-color: #2196f3;
  color: white;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  font-size: 14px;
  transition: background-color 0.2s;
}
.chat-input button:hover {
  background-color: #1976d2;
}
.chat-input button:disabled {
  background-color: #b0bec5;
  cursor: not-allowed;
}
.bot-message:not([data-completed="true"]):after {
  content: "|";
  animation: blink 1s infinite;
  color: #666;
}
@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}
/* 深度思考样式 */
.deepThink {
  color: #666;
  font-style: italic;
  background-color: #f0f0f0;
  padding: 8px 12px;
  border-radius: 8px;
  display: inline-block;
  margin-top: 5px;
}
.thinking-container {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 5px 0;
}
.thinking-icon {
  width: 16px;
  height: 16px;
  opacity: 0.6;
}
</style>
